package com.example.flex.service.impl.generator;

import cn.hutool.core.util.IdUtil;
import com.example.flex.common.exception.BusinessException;
import com.example.flex.domain.generator.ColumnEntity;
import com.example.flex.domain.generator.DataBaseEntity;
import com.example.flex.domain.generator.TableEntity;
import com.example.flex.mapper.generator.DatabaseMapper;
import com.example.flex.service.generator.DatabaseService;
import com.example.flex.utils.db.DataBaseUtil;
import com.example.flex.utils.redis.RedisCache;
import com.example.flex.utils.response.BaseResponse;
import com.google.common.base.CaseFormat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import static com.example.flex.constant.StaticConstant.*;

/**
 * @Author: 不是菜鸡爱编程
 * @Date: 2023/10/27/7:32
 * @Description:
 */
@Slf4j
@Service
public class DatabaseServiceImpl implements DatabaseService {
    @Autowired
    private DatabaseMapper databaseMapper;
    @Autowired
    private RedisCache redisCache;
    @Override
    public List<String> listDatabaseName() {
        return databaseMapper.listDatabaseName();
    }

    @Override
    public BaseResponse<?> connect(DataBaseEntity dataBase) {
        Connection con = DataBaseUtil.initDataBase(dataBase);
        if (con != null) {
            return BaseResponse.success("数据库连接成功");
        }
        return BaseResponse.error("数据库连接失败");
    }

    @Override
    public BaseResponse<?> config(String packageName) throws SQLException {
        Connection connection = DataBaseUtil.getConnection();
        if (connection == null) {
            throw new BusinessException("请先获取数据库连接");
        }
        // 获取数据库信息
        DatabaseMetaData metaData = connection.getMetaData();
        // 获取到表
        ResultSet tables = metaData.getTables(connection.getCatalog(), null, null, null);
        List<TableEntity> tableEntities = new ArrayList<>();
        while (tables.next()) {
            TableEntity tableEntity = new TableEntity();
            tableEntity.setPackageName(packageName);
            String remarks = tables.getString("REMARKS");
            // 数据库中表名
            String tableName = tables.getString(TABLE_NAME);
            tableEntity.setTableName(tableName);
            // 下划线转驼峰后，得到实体类名
            String modelName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName);
            tableEntity.setTableName(tableName);
            tableEntity.setModelName(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName));
            tableEntity.setEntityName(modelName + MODEL_SUFFIX);
            tableEntity.setControllerName(modelName + CONTROLLER_SUFFIX);
            tableEntity.setServiceName(modelName + SERVICE_SUFFIX);
            tableEntity.setServiceImplName(modelName + SERVICE_IMPL_SUFFIX);
            tableEntity.setMapperName(modelName + MAPPER_SUFFIX);
            tableEntity.setListenerName(modelName + LISTENER_SUFFIX);
            //log.info("controller:{}\nservice:{}\nmapper:{}\nentity:{}",tableEntity.getControllerName(),tableEntity.getServiceName(),tableEntity.getMapperName(),tableEntity.getEntityName());
            tableEntity.setRemark(remarks);
            // 添加进入表集合
            tableEntities.add(tableEntity);
        }
        for (TableEntity tableEntity : tableEntities) {
            ResultSet columns = metaData.getColumns(connection.getCatalog(), null, tableEntity.getTableName(), null);
            ResultSet primaryKeys = metaData.getPrimaryKeys(connection.getCatalog(), "%", tableEntity.getTableName());
            List<ColumnEntity> columnEntities = new ArrayList<>();
            while (columns.next()) {
                // 数据库中列名
                String columnName = columns.getString("COLUMN_NAME");
                // 数据库中类型名
                String typeName = columns.getString("TYPE_NAME");
                String remarks = columns.getString("REMARKS");
                ColumnEntity columnEntity = new ColumnEntity();
                columnEntity.setRemark(remarks);
                columnEntity.setColumnName(columnName);
                columnEntity.setType(typeName);
                // 列对应的属性名
                columnEntity.setPropertyName(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, columnName));
                columnEntity.setIsPrimary(false);
                while (primaryKeys.next()) {
                    // 主键名
                    String primaryKeyName = primaryKeys.getString("COLUMN_NAME");
                    columnEntity.setIsPrimary(columnName.equals(primaryKeyName));
                }
                columnEntities.add(columnEntity);
            }
            tableEntity.setColumns(columnEntities);
        }
        String simpleUUID = IdUtil.simpleUUID();
        redisCache.setCacheObject(simpleUUID, tableEntities);
        // 返回存放着实体信息的uuid，信息存储在redis中
        return BaseResponse.success(simpleUUID, "配置成功");
    }
}
